// //******************************************************// // Name: Chris Washington // // E-mail: christopherwashington@hotmail.com // // SID: 462-59-3368 // // Sect: Thursday // // // // Lab Assignment #6 - UART // //******************************************************// // *********** UART Main Module *********** // module UART8 (Serial_out, RCV_Data_Bus, read_not_ready_out, Error1, Error2, Serial_in, XMT_Data_Bus, clk, Sample_clk, read_not_ready_in, rst_, Byte_ready, Load_XMT_datareg, T_byte); input clk, // master clock Sample_clk, // sampling clock(16x master clock) Serial_in, // serial receive line read_not_ready_in, // signals bad data transfer rst_, // asyncronous reset (active low) Byte_ready, // XMT byte loaded on data register Load_XMT_datareg, // copy XMT bus to XMT data register T_byte; // copy data to shift register and begin transfer input [7:0] XMT_Data_Bus; // Transmit data bus output Serial_out, // serial transmit line read_not_ready_out, // data not ready to be read Error1, // bad data transmitted Error2; // OVERFLOW - no stopbit received output [7:0] RCV_Data_Bus; // receive data bus reg [7:0] RCV_Data_Bus; wire [8:0] RCV_datareg; // receive data register // *********** RCV_Data_Bus Control *********** // always @(read_not_ready_out) begin if (read_not_ready_out == 0) RCV_Data_Bus <= RCV_datareg[7:0]; else RCV_Data_Bus <= 8'bxxxx_xxxx; end UART_Receiver R1 (Serial_in, Sample_clk, rst_, read_not_ready_in, RCV_datareg, read_not_ready_out, Error1, Error2); UART_Transmitter X1 (Serial_out, clk, rst_, XMT_Data_Bus, Byte_ready, Load_XMT_datareg, T_byte); // *********** Signal Monitoring for Verification *********** // always @(R1.RCV_datareg) $display (" --> RCV_datareg = %b",R1.RCV_datareg); always @(X1.XMT_datareg) $display (" --> XMT_datareg = %b",X1.XMT_datareg); always @(R1.RCV_shftreg) $display (" --> RCV_shftreg = %b - bitcount = %d",R1.RCV_shftreg,R1.Bit_counter); always @(X1.XMT_shftreg) $display (" --> XMT_shftreg = %b - bitcount = %d",X1.XMT_shftreg,X1.Bit_counter); always @(R1.state) $display (" --> RCV_state = ", R1.state); always @(X1.state) $display (" --> XMT_state = ", X1.state); endmodule //------------------------------------------------------------------------------------------------------------------------------------// // *********** UART Receiver Module *********** // module UART_Receiver (Serial_in, Sample_clk, rst_, read_not_ready_in, RCV_datareg, read_not_ready_out, Error1, Error2); input Serial_in, Sample_clk, rst_, read_not_ready_in; output read_not_ready_out, Error1, Error2; output [8:0] RCV_datareg; reg [8:0] RCV_datareg; reg [8:0] RCV_shftreg; reg inc_Sample_counter, // increment Sample_counter inc_Bit_counter, // increment Bit_counter clr_Bit_counter, // clear Sample_counter clr_Sample_counter, // increment Bit_counter shift, // shift RCV_shftreg in load, // load RCV_shftreg to RCV_datareg read_not_ready_out, Error1, Error2; reg [3:0] Sample_counter; // counts Sample_clk reg [4:0] Bit_counter; // counts bits received reg [1:0] state, next_state; parameter IDLE = 2'b00; parameter STARTING = 2'b01; parameter RECEIVING = 2'b10; always @(posedge Sample_clk or negedge rst_) // Syncronous/Reset Logic begin if (rst_ == 0) // async reset (active low) begin state <= IDLE; RCV_shftreg <= 0; RCV_datareg <= 0; Sample_counter <= 0; Bit_counter <= 0; end else begin state <= next_state; if (clr_Sample_counter == 1) Sample_counter <= 0; // clear Sample_counter else if (inc_Sample_counter == 1) Sample_counter <= Sample_counter + 1; // increment Sample_counter if (clr_Bit_counter == 1) Bit_counter <= 0; // clear Bit_counter else if (inc_Bit_counter == 1) Bit_counter <= Bit_counter + 1; // increment Bit_counter if (shift == 1) RCV_shftreg = {Serial_in, RCV_shftreg[8:1]}; // shift in Serial_in bit to RCV_shftreg if (load == 1) RCV_datareg <= RCV_shftreg; // load RCV_shftreg to RCV_datareg end end always @(state or Serial_in or Sample_counter // Combinational Logic or Bit_counter or read_not_ready_in) begin read_not_ready_out <= 0; inc_Sample_counter <= 0; inc_Bit_counter <= 0; clr_Bit_counter <= 0; clr_Sample_counter <= 0; Error1 <= 0; Error2 <= 0; load <= 0; shift <= 0; case(state) IDLE: if (Serial_in == 0) next_state <= STARTING; STARTING: begin if (Serial_in == 0) inc_Sample_counter <= 1; else begin next_state <= IDLE; clr_Sample_counter <= 1; end if (Sample_counter == 3) begin next_state <= RECEIVING; // Change to receiving after clr_Sample_counter <= 1; // 3 samples of 0 on clk end end RECEIVING: begin inc_Sample_counter <= 1; if (Sample_counter == 15) begin if (Bit_counter == 9) // received all data begin read_not_ready_out <= 1; clr_Sample_counter <= 1; clr_Bit_counter <= 1; next_state <= IDLE; if (read_not_ready_in == 0) begin if (Serial_in == 0) begin Error2 <= 1; $display("*******************ERROR2*******************"); end else load <= 1; // signal load end else begin Error1 <= 1; $display("*******************ERROR1*******************"); end end else // signal bit sample from Serial_in begin shift <= 1; inc_Bit_counter <= 1; clr_Sample_counter <= 1; end end end default: next_state <= IDLE; endcase end endmodule //------------------------------------------------------------------------------------------------------------------------------------// // *********** UART Transmitter Module *********** // module UART_Transmitter (Serial_out, clk, rst_, XMT_Data_Bus, Byte_ready, Load_XMT_datareg, T_byte); input [7:0] XMT_Data_Bus; input Byte_ready, Load_XMT_datareg, T_byte, clk, rst_; output Serial_out; reg [2:0] state, // current state of controller next_state; // next state of controller reg [3:0] Bit_counter; // counts bits transmitted reg [7:0] XMT_datareg; reg [8:0] XMT_shftreg; reg Load_XMT_shftreg, start, // start transmission shift, // shift bit to be transmitted clr_Bit_counter; // clear Bit_counter parameter IDLE = 3'b001; parameter WAITING = 3'b010; parameter SENDING = 3'b100; parameter ALL_ONES = 9'b1_1111_1111; assign Serial_out = XMT_shftreg[0]; always @(posedge clk or negedge rst_) // Syncronous/Reset Logic begin if (rst_ == 0) begin state <= IDLE; Bit_counter <= 0; XMT_shftreg <= ALL_ONES; end else begin state <= next_state; if (Load_XMT_datareg == 1) XMT_datareg <= XMT_Data_Bus; // load XMT_Data_Bus to XMT_datareg if (Load_XMT_shftreg ==1) XMT_shftreg <= {XMT_datareg,1'b1}; // load XMT_shftreg and stop bit if (start == 1) XMT_shftreg[0] <= 0; // start transmission if (clr_Bit_counter == 1) Bit_counter <= 0; // clear Bit_counter else if (shift == 1) Bit_counter <= Bit_counter + 1; // increment Bit_counter if (shift == 1) XMT_shftreg <= {1'b1, XMT_shftreg[8:1]}; // shift out bit to be tranmitted and backfill with stop bit end end always @(state or Byte_ready or Bit_counter or T_byte) // Combinational Logic begin clr_Bit_counter <= 0; Load_XMT_shftreg <= 0; shift <= 0; start <= 0; case(state) IDLE: begin if(Byte_ready == 1) begin Load_XMT_shftreg <= 1; next_state <= WAITING; end else next_state <= IDLE; end WAITING: begin if (T_byte == 1) begin start <= 1; next_state <= SENDING; end else next_state <= WAITING; end SENDING: begin if (Bit_counter != 9) begin shift <= 1; next_state <= SENDING; end else begin clr_Bit_counter <= 1; next_state <= IDLE; end end default next_state <= IDLE; endcase end endmodule